#pragma once

//
// Two static utility class for UTM and Longitude/Latitude conversion
// http://www.ibm.com/developerworks/cn/java/j-coordconvert/
// Usage:
//	wchar_t szUTM[MAX_LENGTH];
//	
//	double dEast = 0.0, dNorth = 0.0;
//	LonLat2UTM::convertLonLatToUTM(23.3545, -45.6456, &dEast, &dNorth, szUTM); 
//
//	double dLon = 0.0, dLat = 0.0;
//	UTM2LonLat::convertUTMToLongLat(szUTM, &dLat, &dLon);
//
//
//Latitude/longitude-to-UTM test value
//
//                
//( 0.0000    0.0000  )     "31 N 166021 0"
//( 0.1300   -0.2324  )     "30 N 808084 14385"
//(-45.6456   23.3545 )     "34 G 683473 4942631"
//(-12.7650  -33.8765 )     "25 L 404859 8588690"
//(-80.5434  -170.6540)     "02 C 506346 1057742"
//( 90.0000   177.0000)     "60 Z 500000 9997964"
//(-90.0000  -177.0000)     "01 A 500000 2035"
//( 90.0000    3.0000 )     "31 Z 500000 9997964"
//( 23.4578  -135.4545)     "08 Q 453580 2594272"
//( 77.3450   156.9876)     "57 X 450793 8586116"
//(-89.3454  -48.9306 )     "22 A 502639 75072"

#include "Macros.h"

class DLLEXPIMP LonLat2UTM
{
public:
	static void convertLonLatToUTM(double longitude, double latitude, double* easting, double* northing, wchar_t* szUTM);	

protected:
	static double getNorthing(double latitude);
	static double getEasting();
	static void SetVariable(double latitude, double longitude);
	static void InitVariable();

private:
	// Lat Lon to UTM variables
	// equatorial radius
	static double equatorialRadius;

	// polar radius
	static double polarRadius;

	// flattening
	static double flattening;// (equatorialRadius-polarRadius)/equatorialRadius;

	// inverse flattening 1/flattening
	static double inverseFlattening;// 1/flattening;

	// Mean radius
	static double rm;

	// scale factor
	static double k0;

	// eccentricity
	static double e;

	static double e1sq;

	static double n;

	// r curv 1
	static double rho;

	// r curv 2
	static double nu;

	// Calculate Meridional Arc Length
	// Meridional Arc
	static double S;

	static double A0;

	static double B0;

	static double C0;

	static double D0;

	static double E0;

	// Calculation ConsMath.Tants
	// Delta Long
	static double p;

	static double sin1;

	// Coefficients for UTM Coordinates
	static double K1;

	static double K2;

	static double K3;

	static double K4;

	static double K5;

	static double A6;
};


class DLLEXPIMP UTM2LonLat
{
public:
	static void convertUTMToLongLat(wchar_t* pszUTM, double* latitude, double* longitude);

protected:
	static wchar_t getHemisphere(wchar_t latzone);
	static void setVariables();

private:
	static double easting;

	static double northing;

	static int zone;

	static wchar_t southernHemisphere[11];

	static double arc;

	static double mu;

	static double ei;

	static double ca;

	static double cb;

	static double cc;

	static double cd;

	static double n0;

	static double r0;

	static double _a1;

	static double dd0;

	static double t0;

	static double Q0;

	static double lof1;

	static double lof2;

	static double lof3;

	static double _a2;

	static double phi1;

	static double fact1;

	static double fact2;

	static double fact3;

	static double fact4;

	static double zoneCM;

	static double _a3;

	static double b;

	static double a;

	static double e;

	static double e1sq;

	static double k0;
};
